
def mouse(block):
    "simulate mouse"
    block = _keyfilter(block)
    block = _movefilter(block)
    return block


####### Mouse Movement ########


_range_move = 3 # use that many older values? not done

_x0, _y0 = 10, -26 # getting a 0 point; if swapXnegY

# from where to where (abs) should be react?
_x0_start, _x0_max = 5, 150
_y0_start, _y0_max = 5, 150

def _distortion(v):
    "strictly increasing,  but nonlinear"
    v3 = (float(v)/10.)**3
    return v3


_x0_scale = _distortion(_x0_max - _x0_start)
_y0_scale = _distortion(_y0_max - _y0_start)
    
_scale = 10 # range between 0 and _scale pixels movement
def _normalize(v, vstart, vmax, scale):
    if -vstart < v < vstart: 
        # not in responding range
        return 0
    # cut out nonresponding bit
    v = v - vstart if v > 0 else v + vstart
    v = _distortion(v) # apply distortion
    # normalize to -1 <= v <= 1
    v = v/scale
    return int(v*_scale)
def _scalex(x):
    return -_normalize(x, _x0_start, _x0_max, _x0_scale)
def _scaley(y):
    return -_normalize(y, _y0_start, _y0_max, _y0_scale)

def _movefilter(block):
    x, y = block[0]["x"]-_x0, block[0]["y"]-_y0
    gox, goy = _scalex(x), _scaley(y)
    if gox != 0:
        block[0]["xmove"] = gox
        # print "gox", gox
    if goy != 0:
        block[0]["ymove"] = goy
        # print "goy", goy
    return block


####### Mouse Buttons #######

# number of events a button is pressed to count as down
# otherwise it is a click
_range_button_down = 5
def _check_down(char, block):
    for i in range(_range_button_down): # been pressed a while
        if char not in block[i]["k"]:
            return False
    if char in block[_range_button_down]["k"]: # not just started 
        return False
    return True

def _check_up(char, block):
    if char in block[0]["k"]:
        return False # still pressed
    # been formerly pressed a while
    for i in range(1, _range_button_down+1): 
        if char not in block[i]["k"]: 
            return False
    return True

def _check_click(char, block):
    if char in block[0]["k"]: # still pressed
        return False
    if char not in block[1]["k"]: # not pressed twice
        return False
    # not pressed now but pressed immediately before
    for i in range (2, _range_button_down+1): # less than down...
        if char not in block[i]["k"]:
            return True
    return False

_mouse_buttons = {
    '#' : 1, # left
    '0' : 2, # middle
    '*' : 3, # right
}

def _keyfilter(block):
    "click detection"
    for char in _mouse_buttons:
        if _check_down(char, block):
            block[0]["down"] = _mouse_buttons[char]
        if _check_up(char, block):
            block[0]["up"] = _mouse_buttons[char]
        if _check_click(char, block):
            block[0]["click"] = _mouse_buttons[char]
    return block
